import { Autocomplete, TextField } from '@mui/material'
import { useCallback, useState, useRef, useEffect } from 'react'
import PropsType from "prop-types";
import { useTranslation } from 'react-i18next';
import useDebounceFn from '../../../Hook/useDebounceFn'

const MyAutoComplete = (props) => {
  const { i18n: { language } } = useTranslation()
  const { className, sx, value, getOptions, renderOption, innerInputLabel, innerInputPlaceholder, variant, required, delay, isRemote, valueProp, labelProp, autoHighlight, focusGetOptions, changeValue } = props
  const isChineseInputting = useRef(false)
  const [inputValue, setInputValue] = useState('')
  const [options, setOptions] = useState([])
  const [loading, setLoading] = useState(false)

  const initialOptions = useCallback(async () => {
    try {
      setLoading(true)
      setOptions([])
      if (getOptions && typeof(getOptions) === 'function') {
        const remoteOptions = await getOptions()
        if (remoteOptions?.length) {
          if (value) {
            const valueItem = remoteOptions.find(item => item[valueProp] === value)
            if (!valueItem) {
              changeValue(null)
            }
          }
          setOptions(remoteOptions)
        } else {
          setOptions([])
        }
      }
      setLoading(false)
    } catch (err) {
      console.log(err)
      setLoading(false)
    }
  }, [getOptions, value])

  useEffect(() => {
    initialOptions()
  }, [])

  const { run } = useDebounceFn(initialOptions, delay, false, [initialOptions, delay])

  const onCompositionStart = useCallback(() => {
    isChineseInputting.current = true
  }, [])

  const onCompositionEnd = useCallback((event) => {
    try {
      isChineseInputting.current = false
      setInputValue(event.target.value)
      if (isRemote) {
        run(event.target.value)
      }
    } catch (err) {
      console.log(err)
    }
  }, [])

  const onChange = useCallback((event, newValue) => {
    if (newValue) {
      changeValue(newValue[valueProp])
    } else {
      changeValue(null)
    }
  }, [])

  const onInputChange = useCallback((event) => {
    try {
      if (!isChineseInputting.current) {
        setInputValue(event.target.value)
        if (isRemote) {
          run(event.target.value)
        }
      }
    } catch (err) {
      console.log(err)
    }
  }, [])

  const isOptionEqualToValue = useCallback((option, value) => {
    if (option[valueProp] === value) {
      return true
    }
    return false
  }, [valueProp])
  
  const getOptionLabel = useCallback((value) => {
    if (options.length && value) {
      if (typeof(value) !== 'object') {
        const item = options.find(op => op[valueProp] === value)
        if (item) {
          if (item[labelProp] && item[labelProp].i18nValue) {
            return item[labelProp].i18nValue[language] ? item[labelProp].i18nValue[language] : item[labelProp].defaultValue
          }
          return item[labelProp]
        }
        return ''
      }
      return value[labelProp].i18nValue ? value[labelProp].i18nValue[language] ? value[labelProp].i18nValue[language] : value[labelProp].defaultValue : value[labelProp]
    }
    return ''
  }, [language, labelProp, options, valueProp])

  const getOptionKey = useCallback((option) => {
    return option[valueProp]
  }, [valueProp])

  const onFocus = useCallback(() => {
    if (focusGetOptions) {
      initialOptions()
    }
  }, [focusGetOptions, initialOptions])

  return (
    <Autocomplete sx={{ width: '100%', ...sx }}
      className={className}
      value={value}
      loading={loading}
      options={options}
      autoHighlight={autoHighlight}
      onChange={onChange}
      getOptionLabel={getOptionLabel}
      getOptionKey={getOptionKey}
      renderOption={renderOption}
      // onInputChange={onInputChange}
      isOptionEqualToValue={isOptionEqualToValue}
      renderInput={(params) => (
        <TextField
          {...params}
          label={innerInputLabel}
          placeholder={innerInputPlaceholder}
          variant={variant}
          required={required}
          value={inputValue}
          onChange={onInputChange}
          inputProps={{
            ...params.inputProps
          }}
          onCompositionEnd={onCompositionEnd}
          onCompositionStart={onCompositionStart}
          onFocus={onFocus}
        />
      )}
    >
    </Autocomplete>
  )
}

MyAutoComplete.propTypes = {
  sx: PropsType.string,
  className: PropsType.string,
  getOptions: PropsType.func.isRequired,
  innerInputLabel: PropsType.string,
  innerInputPlaceholder: PropsType.string,
  variant: PropsType.string,
  required: PropsType.bool,
  delay: PropsType.number,
  isRemote: PropsType.bool,
  valueProp: PropsType.string.isRequired,
  labelProp: PropsType.string.isRequired,
  autoHighlight: PropsType.bool,
  focusGetOptions: PropsType.bool,
  changeValue: PropsType.func.isRequired
}

MyAutoComplete.defaultProps = {
  innerInputLabel: '',
  innerInputPlaceholder: '',
  variant: 'filled',
  required: false,
  delay: 0,
  isRemote: false,
  autoHighlight: false,
  focusGetOptions: false
}

export default MyAutoComplete